package com.cheng.spring03.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class LoggerAspect {
    private static final String EXECUTION = "execution(* com.cheng.spring03.service.*.*(..))";

    /**
     * @param joinPoint 连接点
     *                  前置通知
     */
    //@Before(EXECUTION)
    public void beforeAdvice(JoinPoint joinPoint) {
        System.out.println("执行" + joinPoint.getSignature().getName() + "前置通知");
    }

    /**
     * 最终通知，在目标方法执行结束后执行增强逻辑（无论是否抛出异常）
     */
    //@After(EXECUTION)
    public void afterAdvice(JoinPoint joinPoint) {
        System.out.println("执行" + joinPoint.getSignature().getName() + "最终通知");
    }

    /**
     * 后置通知，在目标方法成功执行完成后执行增强逻辑
     */
    //@AfterReturning(pointcut = EXECUTION, returning = "result")
    public void afterReturningAdvice(JoinPoint joinPoint, Object result) {
        System.out.println("执行" + joinPoint.getSignature().getName() + "后置通知");
        System.out.println("方法执行完成的返回值" + result);
    }

    /**
     * 异常通知，在目标方法抛出异常后执行增强逻辑
     */
    //@AfterThrowing(pointcut = EXECUTION,throwing = "exception")
    public void afterThrowingAdvice(JoinPoint joinPoint,Exception exception) {
        System.out.println("执行" + joinPoint.getSignature().getName() + "异常通知");
        System.out.println("异常信息" + exception);
    }

    /**
     * 环绕通知，功能最全的通知
     */
    @Around(EXECUTION)
    public void aroundAdvice(ProceedingJoinPoint joinPoint){
        System.out.println("执行" + joinPoint.getSignature().getName() + "前置通知");
        try {
            // 执行目标方法
            Object result = joinPoint.proceed();
            System.out.println("执行" + joinPoint.getSignature().getName() + "后置通知");
            System.out.println("方法执行完成的返回值" + result);
        } catch (Throwable e) {
            System.out.println("执行" + joinPoint.getSignature().getName() + "异常通知");
            System.out.println("异常信息" + e);
        } finally {
            System.out.println("执行" + joinPoint.getSignature().getName() + "最终通知");
        }
    }
}
